<!DOCTYPE html>
<html lang="en">
<head>
        <meta charset="utf-8" />
        <title>Part.2.D.8-main</title>
        <link rel="stylesheet" href="/theme/css/main.css" />

        <!--[if IE]>
            <script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
        <![endif]-->
</head>

<body id="index" class="home">
        <header id="banner" class="body">
                <h1><a href="/">PythonTutorials </a></h1>
                <nav><ul>
                    <li><a href="/category/cpp.html">cpp</a></li>
                    <li class="active"><a href="/category/python.html">python</a></li>
                </ul>
                </nav>
        </header><!-- /#banner -->
<section id="content" class="body">
  <article>
    <header>
      <h1 class="entry-title">
        <a href="/Part.2.D.8-main.html" rel="bookmark"
           title="Permalink to Part.2.D.8-main">Part.2.D.8-main</a></h1>
    </header>

    <div class="entry-content">
<footer class="post-info">
        <span>Mon 06 April 2020</span>
<span>| tags: <a href="/tag/python.html">python</a><a href="/tag/progarmming.html">progarmming</a><a href="/tag/excel.html">Excel</a></span>
</footer><!-- /.post-info -->      <h1>可执行的 Python 文件</h1>
<p>理论上来讲，你最终可以把任何一个程序，无论大小，都封装（或者囊括）到仅仅一个函数之中。按照惯例（Convention），这个函数的名称叫做 <code>main()</code>：</p>
<div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">routine_1</span><span class="p">():</span>
    <span class="k">print</span><span class="p">(</span><span class="s1">&#39;Routine 1 done.&#39;</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">routine_2</span><span class="p">():</span>
    <span class="n">sub_routine_1</span><span class="p">()</span>
    <span class="n">sub_routine_2</span><span class="p">()</span>
    <span class="k">print</span><span class="p">(</span><span class="s1">&#39;Routine 2 done.&#39;</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">sub_routine_1</span><span class="p">():</span>
    <span class="k">print</span><span class="p">(</span><span class="s1">&#39;Sub-routine 1 done.&#39;</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">sub_routine_2</span><span class="p">():</span>
    <span class="k">print</span><span class="p">(</span><span class="s1">&#39;Sub-routine 2 done.&#39;</span><span class="p">)</span>

<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
    <span class="n">routine_1</span><span class="p">()</span>
    <span class="n">routine_2</span><span class="p">()</span>
    <span class="k">print</span><span class="p">(</span><span class="s1">&#39;This is the end of the program.&#39;</span><span class="p">)</span>

<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>


<div class="highlight"><pre><span></span>Routine 1 done.
Sub-routine 1 done.
Sub-routine 2 done.
Routine 2 done.
This is the end of the program.
</pre></div>


<p>当一个模块（其实就是存有 Python 代码的 <code>.py</code> 文件，例如：<code>mycode.py</code>）被 <code>import</code> 语句导入的时候，这个模块的 <code>__name__</code> 就是模块名（例如：<code>'mycode'</code>）。</p>
<p>而当一个模块被命令行运行的时候，这个模块的 <code>__name__</code> 就被 Python 解释器设定为 <code>'__main__'</code>。</p>
<p>把一个程序整个封装到 <code>main()</code> 之中，而后在模块代码里加上：</p>
<div class="highlight"><pre><span></span><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>


<p>这么做的结果是：</p>
<blockquote>
<ol>
<li>当 Python 文件被当作模块，被 <code>import</code> 语句导入时，<code>if</code> 判断失败，<code>main()</code> 函数不被执行；</li>
<li>当 Python 文件被 <code>python -m</code> 运行的时候，<code>if</code> 判断成功，<code>main()</code> 函数才被执行。</li>
</ol>
</blockquote>
<p>还记得那个 Python 的彩蛋吧？<code>this.py</code> 的代码如下：</p>
<div class="highlight"><pre><span></span><span class="n">s</span> <span class="o">=</span> <span class="s2">&quot;&quot;&quot;Gur Mra bs Clguba, ol Gvz Crgref</span>
<span class="s2">Ornhgvshy vf orggre guna htyl.</span>
<span class="s2">Rkcyvpvg vf orggre guna vzcyvpvg.</span>
<span class="s2">Fvzcyr vf orggre guna pbzcyrk.</span>
<span class="s2">Pbzcyrk vf orggre guna pbzcyvpngrq.</span>
<span class="s2">Syng vf orggre guna arfgrq.</span>
<span class="s2">Fcnefr vf orggre guna qrafr.</span>
<span class="s2">Ernqnovyvgl pbhagf.</span>
<span class="s2">Fcrpvny pnfrf nera&#39;g fcrpvny rabhtu gb oernx gur ehyrf.</span>
<span class="s2">Nygubhtu cenpgvpnyvgl orngf chevgl.</span>
<span class="s2">Reebef fubhyq arire cnff fvyragyl.</span>
<span class="s2">Hayrff rkcyvpvgyl fvyraprq.</span>
<span class="s2">Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.</span>
<span class="s2">Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.</span>
<span class="s2">Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh&#39;er Qhgpu.</span>
<span class="s2">Abj vf orggre guna arire.</span>
<span class="s2">Nygubhtu arire vf bsgra orggre guna *evtug* abj.</span>
<span class="s2">Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg&#39;f n onq vqrn.</span>
<span class="s2">Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.</span>
<span class="s2">Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg&#39;f qb zber bs gubfr!&quot;&quot;&quot;</span>

<span class="n">d</span> <span class="o">=</span> <span class="p">{}</span>
<span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">65</span><span class="p">,</span> <span class="mi">97</span><span class="p">):</span>
    <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">26</span><span class="p">):</span>
        <span class="n">d</span><span class="p">[</span><span class="nb">chr</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="n">c</span><span class="p">)]</span> <span class="o">=</span> <span class="nb">chr</span><span class="p">((</span><span class="n">i</span><span class="o">+</span><span class="mi">13</span><span class="p">)</span> <span class="o">%</span> <span class="mi">26</span> <span class="o">+</span> <span class="n">c</span><span class="p">)</span>

<span class="k">print</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">d</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">s</span><span class="p">]))</span>
</pre></div>


<p>所以，只要 <code>import this</code>，<code>this.py</code> 中的代码就被执行：</p>
<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">this</span>
</pre></div>


<p>我在当前目录下，保存了一个文件 <code>that.py</code>，它的内容如下 —— 其实就是把 <code>this.py</code> 之中的代码封装到 <code>main()</code> 函数中了：</p>
<div class="highlight"><pre><span></span><span class="c1"># %load that.py</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">():</span>

    <span class="n">s</span> <span class="o">=</span> <span class="s2">&quot;&quot;&quot;Gur Mra bs Clguba, ol Gvz Crgref</span>
<span class="s2">    Ornhgvshy vf orggre guna htyl.</span>
<span class="s2">    Rkcyvpvg vf orggre guna vzcyvpvg.</span>
<span class="s2">    Fvzcyr vf orggre guna pbzcyrk.</span>
<span class="s2">    Pbzcyrk vf orggre guna pbzcyvpngrq.</span>
<span class="s2">    Syng vf orggre guna arfgrq.</span>
<span class="s2">    Fcnefr vf orggre guna qrafr.</span>
<span class="s2">    Ernqnovyvgl pbhagf.</span>
<span class="s2">    Fcrpvny pnfrf nera&#39;g fcrpvny rabhtu gb oernx gur ehyrf.</span>
<span class="s2">    Nygubhtu cenpgvpnyvgl orngf chevgl.</span>
<span class="s2">    Reebef fubhyq arire cnff fvyragyl.</span>
<span class="s2">    Hayrff rkcyvpvgyl fvyraprq.</span>
<span class="s2">    Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff.</span>
<span class="s2">    Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg.</span>
<span class="s2">    Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh&#39;er Qhgpu.</span>
<span class="s2">    Abj vf orggre guna arire.</span>
<span class="s2">    Nygubhtu arire vf bsgra orggre guna *evtug* abj.</span>
<span class="s2">    Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg&#39;f n onq vqrn.</span>
<span class="s2">    Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn.</span>
<span class="s2">    Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg&#39;f qb zber bs gubfr!&quot;&quot;&quot;</span>

    <span class="n">d</span> <span class="o">=</span> <span class="p">{}</span>
    <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="p">(</span><span class="mi">65</span><span class="p">,</span> <span class="mi">97</span><span class="p">):</span>
        <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">26</span><span class="p">):</span>
            <span class="n">d</span><span class="p">[</span><span class="nb">chr</span><span class="p">(</span><span class="n">i</span><span class="o">+</span><span class="n">c</span><span class="p">)]</span> <span class="o">=</span> <span class="nb">chr</span><span class="p">((</span><span class="n">i</span><span class="o">+</span><span class="mi">13</span><span class="p">)</span> <span class="o">%</span> <span class="mi">26</span> <span class="o">+</span> <span class="n">c</span><span class="p">)</span>

    <span class="k">print</span><span class="p">(</span><span class="s2">&quot;&quot;</span><span class="o">.</span><span class="n">join</span><span class="p">([</span><span class="n">d</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">c</span><span class="p">,</span> <span class="n">c</span><span class="p">)</span> <span class="k">for</span> <span class="n">c</span> <span class="ow">in</span> <span class="n">s</span><span class="p">]))</span>

<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">()</span>
</pre></div>


<p>于是，当你在其它地方导入它的时候，<code>import that</code>，<code>main()</code> 函数的内容不会被执行：</p>
<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">that</span>
</pre></div>


<p>但是，你在命令行中，用 <code>python that.py</code>，或者 <code>python -m that</code> 将 <code>that.py</code> 当作可执行模块运行的时候，<code>main()</code> 就会被执行 —— 注意，不要写错，<code>python -m that.py</code> 会报错的 —— 有 <code>-m</code> 参数，就不要写文件尾缀 <code>.py</code>：</p>
<div class="highlight"><pre><span></span>%%bash
python that.py
</pre></div>


<div class="highlight"><pre><span></span>%%bash
python -m that
</pre></div>


<p>像 <code>that.py</code> 那样把整个程序放进 <code>main()</code> 函数之后，<code>import that</code> 不会自动执行 main 函数里的代码。不过，你可以调用 that.main()：</p>
<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">that</span>
<span class="n">that</span><span class="o">.</span><span class="n">main</span><span class="p">()</span>
</pre></div>


<p>当然，<code>that.py</code> 之中没有任何 Docstring，所以 <code>help(that)</code> 的结果是这样的：</p>
<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">that</span>
<span class="n">help</span><span class="p">(</span><span class="n">that</span><span class="p">)</span>
</pre></div>


<p>所以，之前那个从 37 万多个词汇中挑出 3700 多个字母加起来等于 100 的词汇的程序，也可以写成以下形式：</p>
<div class="highlight"><pre><span></span><span class="ch">#!/usr/bin/env python</span>

<span class="k">def</span> <span class="nf">sum_of_word</span><span class="p">(</span><span class="n">word</span><span class="p">):</span>
    <span class="nb">sum</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">for</span> <span class="n">char</span> <span class="ow">in</span> <span class="n">word</span><span class="p">:</span>
        <span class="nb">sum</span> <span class="o">+=</span> <span class="nb">ord</span><span class="p">(</span><span class="n">char</span><span class="p">)</span> <span class="o">-</span> <span class="mi">96</span>
    <span class="k">return</span> <span class="nb">sum</span>
<span class="k">def</span> <span class="nf">main</span><span class="p">(</span><span class="n">wordlist</span><span class="p">,</span> <span class="n">result</span><span class="p">):</span>
    <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">result</span><span class="p">,</span> <span class="s1">&#39;w&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="n">result</span><span class="p">:</span>
        <span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="n">wordlist</span><span class="p">,</span> <span class="s1">&#39;r&#39;</span><span class="p">)</span> <span class="k">as</span> <span class="nb">file</span><span class="p">:</span>
            <span class="k">for</span> <span class="n">word</span> <span class="ow">in</span> <span class="nb">file</span><span class="o">.</span><span class="n">readlines</span><span class="p">():</span>
                <span class="k">if</span> <span class="n">sum_of_word</span><span class="p">(</span><span class="n">word</span><span class="o">.</span><span class="n">strip</span><span class="p">())</span> <span class="o">==</span> <span class="mi">100</span><span class="p">:</span>
                    <span class="n">result</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="n">word</span><span class="p">)</span>

<span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s1">&#39;__main__&#39;</span><span class="p">:</span>
    <span class="n">main</span><span class="p">(</span><span class="s1">&#39;words_alpha.txt&#39;</span><span class="p">,</span> <span class="s1">&#39;results.txt&#39;</span><span class="p">)</span>
</pre></div>


<p>至于以上代码中的第一行，<code>#!/usr/bin/env python</code> 是怎么回事，建议你自己动手解决一下，去 Google：</p>
<blockquote>
<p><a href="https://www.google.com/search?q=python3+script+executable"><code>python3 script executable</code></a></p>
</blockquote>
<p>你会很快弄明白的……</p>
<p>另外，再搜索一下：</p>
<blockquote>
<p><a href="https://www.google.com/search?q=python3+script+executable+parameters+retrieving"><code>python3 script executable parameters retrieving</code></a></p>
</blockquote>
<p>你就可以把以上程序改成在命令行下能够接收指定参数的 Python 可执行文件……</p>
<p>顺带说，<code>import this</code> 的彩蛋有更好玩的玩法：</p>
<div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">IPython.core.interactiveshell</span> <span class="kn">import</span> <span class="n">InteractiveShell</span>
<span class="n">InteractiveShell</span><span class="o">.</span><span class="n">ast_node_interactivity</span> <span class="o">=</span> <span class="s2">&quot;all&quot;</span>

<span class="kn">import</span> <span class="nn">this</span>
<span class="n">love</span> <span class="o">=</span> <span class="n">this</span>
<span class="n">this</span> <span class="ow">is</span> <span class="n">love</span>                            <span class="c1"># True</span>
<span class="n">love</span> <span class="ow">is</span> <span class="bp">True</span>                            <span class="c1"># False</span>
<span class="n">love</span> <span class="ow">is</span> <span class="bp">False</span>                           <span class="c1"># False</span>
<span class="n">love</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">True</span> <span class="ow">or</span> <span class="bp">False</span>               <span class="c1"># True</span>
<span class="n">love</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">True</span> <span class="ow">or</span> <span class="bp">False</span><span class="p">;</span> <span class="n">love</span> <span class="ow">is</span> <span class="n">love</span> <span class="c1"># True True</span>
</pre></div>


<div class="highlight"><pre><span></span>True
False
False
True
True
True
</pre></div>


<p>在 Terminal 里输入 <code>python ⏎</code> 而后在 Interactive Shell 里逐句输入试试。<code>love = this</code> 后面的每一句，都是布尔运算，想想看为什么是那样的结果？</p>
<div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">this</span>
<span class="n">love</span> <span class="o">=</span> <span class="n">this</span>

<span class="n">this</span> <span class="ow">is</span> <span class="n">love</span>
<span class="c1"># True, 试试看，id(this) 和 id(love) 是同一个值</span>
<span class="c1"># 即，它们的内存地址相同</span>

<span class="n">love</span> <span class="ow">is</span> <span class="bp">True</span>
<span class="c1"># False, id(love) 和 id(True) 不是同一个值</span>
<span class="n">love</span> <span class="ow">is</span> <span class="bp">False</span>
<span class="c1"># 同上</span>

<span class="n">love</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">True</span> <span class="ow">or</span> <span class="bp">False</span>
<span class="c1"># is not 的优先级比 or 高；所以相当于是：</span>
<span class="c1"># (love is not True) or False，于是返回 True</span>

<span class="n">love</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">True</span> <span class="ow">or</span> <span class="bp">False</span><span class="p">;</span> <span class="n">love</span> <span class="ow">is</span> <span class="n">love</span>
<span class="c1"># 重复一次上一句 —— `;` 是语句分隔符</span>
<span class="c1"># 而后 love is love 当然是 True</span>
</pre></div>


<p>注意以下代码中，<code>id()</code> 函数的输出结果：</p>
<div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">IPython.core.interactiveshell</span> <span class="kn">import</span> <span class="n">InteractiveShell</span>
<span class="n">InteractiveShell</span><span class="o">.</span><span class="n">ast_node_interactivity</span> <span class="o">=</span> <span class="s2">&quot;all&quot;</span>

<span class="kn">import</span> <span class="nn">this</span>
<span class="n">love</span> <span class="o">=</span> <span class="n">this</span>
<span class="n">this</span> <span class="ow">is</span> <span class="n">love</span>
<span class="n">love</span> <span class="ow">is</span> <span class="bp">True</span>
<span class="n">love</span> <span class="ow">is</span> <span class="bp">False</span>
<span class="n">love</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">True</span> <span class="ow">or</span> <span class="bp">False</span>
<span class="n">love</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">True</span> <span class="ow">or</span> <span class="bp">False</span><span class="p">;</span> <span class="n">love</span> <span class="ow">is</span> <span class="n">love</span>
<span class="nb">id</span><span class="p">(</span><span class="n">love</span><span class="p">)</span>
<span class="nb">id</span><span class="p">(</span><span class="n">this</span><span class="p">)</span>
<span class="nb">id</span><span class="p">(</span><span class="bp">True</span><span class="p">)</span>
<span class="nb">id</span><span class="p">(</span><span class="bp">False</span><span class="p">)</span>
<span class="n">love</span> <span class="ow">is</span> <span class="ow">not</span> <span class="bp">True</span>
</pre></div>


<div class="highlight"><pre><span></span>True
False
False
True
True
True
4345330968
4345330968
4308348176
4308349120
True
</pre></div>


<p>Python 的操作符优先级，完整表格在这里：</p>
<blockquote>
<p><a href="https://docs.python.org/3/reference/expressions.html#operator-precedence">Operator precedence</a></p>
</blockquote>
<p>Python 的更多彩蛋：</p>
<blockquote>
<p><a href="https://github.com/OrkoHunter/python-easter-eggs">Python Easter Eggs</a></p>
</blockquote>
    </div><!-- /.entry-content -->

  </article>
</section>
        <section id="extras" class="body">
                <div class="blogroll">
                        <h2>blogroll</h2>
                        <ul>
                            <li><a href="http://getpelican.com/">Pelican</a></li>
                            <li><a href="http://python.org/">Python.org</a></li>
                            <li><a href="http://jinja.pocoo.org/">Jinja2</a></li>
                            <li><a href="#">You can modify those links in your config file</a></li>
                        </ul>
                </div><!-- /.blogroll -->
                <div class="social">
                        <h2>social</h2>
                        <ul>

                            <li><a href="#">You can add links in your config file</a></li>
                            <li><a href="#">Another social link</a></li>
                        </ul>
                </div><!-- /.social -->
        </section><!-- /#extras -->

        <footer id="contentinfo" class="body">
                <p>Powered by <a href="http://www.maxiaoan.com/">Maxiaoan</a></p>
        </footer><!-- /#contentinfo -->

</body>
</html>